<template>
  <div>
    <div @click="openClick">
      <slot :value="obj[objKey]"></slot>
    </div>
    <van-popup v-model="elPopup" position="bottom" close-on-popstate get-container="#app">
      <!-- 自定义选项 -->
      <van-picker
        v-if="type=='select'"
        v-model="elValue"
        :default-index="elSelectIndex"
        :columns="selectOption"
        :value-key="selectLabelkey"
        show-toolbar
        @confirm="changeClick"
        @cancel="elPopup=false"
      />
      <!-- 日期 -->
      <van-datetime-picker
        v-else-if="type=='month'||type=='date'||type=='datetime'"
        v-model="elValue"
        :type="type=='month'?'year-month':type"
        @confirm="changeClick"
        @cancel="elPopup=false"
      />
      <!-- 时间间隔 -->
      <van-datetime-picker
        v-else-if="type=='timestep'"
        v-model="elValue"
        :min-hour="minHour"
        :max-hour="maxHour"
        :min-minute="minMinute"
        :max-minute="maxMinute"
        type="time"
        :filter="timestepFilter"
        @confirm="changeClick"
        @cancel="elPopup=false"
      />
      <!-- 地区 -->
      <van-area
        v-else-if="type=='province'||type=='city'||type=='district'"
        v-model="elValue"
        :area-list="areaObj"
        :columns-num="type=='province'?1:(type=='city'?2:3)"
        @confirm="changeAreaClick"
        @cancel="elPopup=false"
      />
    </van-popup>
  </div>
</template>

<script>
import api from "@/api/api";
import { Popup, Picker, DatetimePicker, Area } from "vant";
export default {
  components: {
    "van-popup": Popup,
    "van-picker": Picker,
    "van-datetime-picker": DatetimePicker,
    "van-area": Area
  },

  props: {
    obj: {// InputObj
      type: Object,
      default: function () {
        return api.createInputObj();
      }
    },

    objKey: {// 数据对应InputObj的key值
      type: String,
      default: ""
    },

    prefix: {// 提示的文本内容
      type: String,
      default: null
    },

    /**
     * 自定义选项（对应selectOption、selectLabelkey）：select
     * 日期：month、date、datetime
     * 时间间隔（对应timestepOption、timestepMinute）：timestep
     * 地区：province、city、district
     */
    type: {
      type: String,
      default: "select"
    },

    selectOption: {// 对应select的数组
      type: Array,
      default: null
    },

    selectLabelkey: {// 对应select的数组的显示值的key
      type: String,
      default: null
    },

    timestepOption: {// 对应timestep的时间限制
      type: String,
      default: "00:00-23:59"
    },

    timestepMinute: {// 对应timestep的时间间隔的分钟数
      type: Number,
      default: 1
    },

    required: {// 是否必填
      type: Boolean,
      default: false
    },

    disabled: {// 是否不可用
      type: Boolean,
      default: false
    }
  },

  data() {
    return {
      elValue: null,
      elPopup: false,
      minHour: null,
      maxHour: null,
      minMinute: null,
      maxMinute: null
    }
  },

  computed: {
    elSelectIndex() {
      if (this.type == "select") {
        if (this.selectOption) {
          let index = this.selectOption.indexOf(this.elValue);
          if (index > -1) {
            return index;
          }
        }
      }
      return 0;
    },

    areaObj() {
      if (this.type == "province" || this.type == "city" || this.type == "district") {
        let baseArea = require("../../utils/baseArea");
        let areaObj = {};
        areaObj.province_list = {};
        for (let i in baseArea) {
          let srcItem = baseArea[i];
          areaObj.province_list[this.getAreaCode(i)] = srcItem.n;
          if (this.type == "city" || this.type == "district") {
            if (!areaObj.city_list) {
              areaObj.city_list = {};
            }
            for (let j in srcItem.c) {
              let srcSubItem = srcItem.c[j];
              areaObj.city_list[this.getAreaCode(j)] = srcSubItem.n;
              if (this.type == "district") {
                if (!areaObj.county_list) {
                  areaObj.county_list = {};
                }
                for (let k in srcSubItem.c) {
                  let srcPopItem = srcSubItem.c[k];
                  areaObj.county_list[this.getAreaCode(k)] = srcPopItem.n;
                }
              }
            }
          }
        }
        return areaObj;
      }
      return null;
    }
  },

  watch: {
    obj() {
      this.register();
    },

    objKey() {
      this.register();
    },

    type() {
      this.changeClick(null);
    },

    timestepOption() {
      if (this.type == "timestep") {
        this.timeParse(this.timestepOption);
      }
    }
  },

  mounted() {
    this.register();
    if (this.type == "timestep") {
      this.timeParse(this.timestepOption);
    }
  },

  destroyed() {
    this.obj._unRegister(this.objKey);
  },

  methods: {
    register() {
      let self = this;
      this.obj._watch(this.objKey, function (value) {
        if (self.type == "province" || self.type == "city" || self.type == "district") {
          self.elValue = self.getAreaValue(value);
        } else {
          self.elValue = value;
        }
      }, function (value) {
        if (self.type == "month" || self.type == "date" || self.type == "datetime") {
          if (!value) {
            value = new Date();
          }
        }
        return value;
      });
      this.obj._register(this.objKey, function () {
        let prefix = self.prefix;
        if (!prefix) {
          let type = self.type;
          if (type == "month" || type == "date" || type == "datetime") {
            prefix = "日期";
          } else if (type == "timestep") {
            prefix = "时间";
          } else if (type == "province" || type == "city" || type == "district") {
            prefix = "地区";
          } else {
            prefix = "内容";
          }
        }
        return self.checkData(self.obj[self.objKey], self.required, prefix);
      });
    },

    checkData(data, required, prefix) {
      let result = api.verifyData(data, null);
      if (result.data == null || result.data.length < 1) {
        if (required) {// 非空判断
          api.toast("请选择" + prefix);
          return false;
        }
        return true;
      }
      return result.success;
    },

    changeAreaClick(value) {
      if (value) {
        let array = []
        value.forEach(item => {
          if (item) {
            array.push(item.name);
          }
        });
        value = array;
      }
      this.changeClick(value);
    },

    changeClick(value) {
      this.obj[this.objKey] = value;
      this.$emit("change", value);
      this.elPopup = false;
    },

    openClick() {
      if (!this.disabled) {
        this.elPopup = true;
      }
    },

    timeParse(option) {
      if (!option) {
        return;
      }
      let array = option.split("-");
      if (array.length != 2) {
        return;
      }
      let subArray = array[0].split(":");
      if (subArray.length != 2) {
        return;
      }
      let subArray2 = array[1].split(":");
      if (subArray2.length != 2) {
        return;
      }
      this.minHour = subArray[0];
      this.minMinute = subArray[1];
      this.maxHour = subArray2[0];
      this.maxMinute = subArray2[1];
    },

    timestepFilter(type, options) {
      if (this.timestepMinute > 60) {
        let hour = this.timestepMinute / 60;
        let minute = this.timestepMinute % 60;
        if (type === "hour") {
          options = options.filter(option => option % hour == 0);
        } else if (type === "minute") {
          if (minute > 1) {
            options = options.filter(option => option % minute == 0);
          }
        }
      } else if (this.timestepMinute > 1) {
        if (type === "minute") {
          options = options.filter(option => option % this.timestepMinute == 0);
        }
      }
      return options;
    },

    getAreaValue(array) {
      if (!array) {
        return null;
      }
      let item = null;
      let list = null;
      if (this.type == "province") {
        if (array.length == 1) {
          item = array[0];
          list = this.areaObj.province_list;
        }
      } else if (this.type == "city") {
        if (array.length == 2) {
          item = array[1];
          list = this.areaObj.city_list;
        }
      } else if (this.type == "district") {
        if (array.length == 3) {
          item = array[2];
          list = this.areaObj.county_list;
        }
      }
      if (item && list) {
        for (let key in list) {
          if (item == list[key]) {
            return key;
          }
        }
      }
      return null;
    },

    getAreaCode(num) {
      let len = 6 - (num + "").length;
      if (len > 0) {
        for (let i = 0; i < len; i++) {
          num += "0";
        }
      }
      return Number(num);
    }
  }
}
</script>